package com.eshipenet.shipnet.edpersistor

import org.json4s._

import scala.util.Try

sealed trait TSDBDataField
case class TSDBDataFieldInt(value: Long)      extends TSDBDataField
case class TSDBDataFieldFloat(value: Double)  extends TSDBDataField
case class TSDBDataFieldString(value: String) extends TSDBDataField
case class TSDBDataFieldBool(value: Boolean)  extends TSDBDataField

case class TSDBData(timestamp: Long, measurement: String, tags: Map[String, String], fields: Map[String, TSDBDataField])

object TSDBData {

  def build(data: EquipmentData, processTimestamp: Long): Try[Iterable[TSDBData]] = Try {
    val timestamp   = data.timestamp
    val measurement = data.model.id
    val tags = Map(
      "equipmentName"      -> data.equipment.name,
      "equipmentModelName" -> data.model.name,
      "producer"           -> "kafka",
      "equipmentId"        -> data.equipment.id,
      "influxdb_database"  -> "equipmenttest3",
    )
    val fields = data.data
      .map { kv =>
        val field = kv._2.value match {
          case JNothing      => None
          case JNull         => None
          case JInt(num)     => Some(TSDBDataFieldFloat(num.toLong))
          case JLong(num)    => Some(TSDBDataFieldFloat(num))
          case JDouble(num)  => Some(TSDBDataFieldFloat(num))
          case JDecimal(num) => Some(TSDBDataFieldFloat(num.toDouble))
          case JBool(b)      => Some(TSDBDataFieldBool(b))
          case JString(s)    => Some(TSDBDataFieldString(s))
          case x             => Some(TSDBDataFieldString(x.toString))
        }
        kv._1 -> field
      }
      .filter(_._2.isDefined)
      .mapValues(_.get)
    val exFields = Map(
      "processTimestamp" -> TSDBDataFieldInt(processTimestamp)
    )
    val d = TSDBData(timestamp, measurement, tags, fields ++ exFields)
    Set(d)
  }

}
